package be.artesis.titamo.importer.gui;

import java.awt.Component;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.prefs.Preferences;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import be.artesis.titamo.exceptions.BindingException;
import be.artesis.titamo.exceptions.DriverNotFoundException;
import be.artesis.titamo.exceptions.InterfaceNotFoundException;
import be.artesis.titamo.exceptions.TimeTableParserErrors;
import be.artesis.titamo.exceptions.ToleranceReachedException;
import be.artesis.titamo.importer.ImporterInterface;
import be.artesis.titamo.importer.InterfaceConst;
import be.artesis.titamo.importer.MainExecutable;
import be.artesis.titamo.importer.gui.filefilter.SupportedFileFilter;
import be.artesis.titamo.importer.gui.filefilter.TTDFFileFilter;
import be.artesis.titamo.importer.gui.filefilter.TXTFileFilter;
import be.artesis.titamo.io.SQLDatabase;
import be.artesis.titamo.tools.StringTools;


public class GraphicalInterface extends ImporterInterface implements ActionListener, FocusListener
{
	private static final int OPTIONSLABEL_GAP = 5;
	private static final int SMALL_GAP = 5;
	private static final int INTEROPTIONS_GAP = 20;
	private static final int FIELDLABEL_GAP = 10;
	private static final int TABBELLABEL_GAP = 50;
	
	private static final long serialVersionUID = -3958492918008324708L;

	private static final String TITLE = "Titamo TimeTable Importer v1.0a";
	

	// advanced Options array
	private ComponentGroup advancedOptions;
	private JPanel optionPanelWrapper;
	// Frame
	private JFrame frame;
	
	// FILE PANEL COMPONENTS
	private JTextField fileField;
	private JButton browseButton;
	
	// OPTION PANEL COMPONENTS
	private JCheckBox clearBox;
	private JTextField delimiterField;
	private JTextField subdelimiterField;
	private JCheckBox advancedCheckBox;
	
	//private JTextField serverDBSystemField;
	private JTextField serverIPField;
	private JTextField serverPortField;
	private JTextField usernameField;
	private JPasswordField passwordField;
	private JComboBox serverTypeCombo;
	private JTextField databaseNameField;

	private JTextField tableNameField;

	private JTextField customStringField;
	
	//IMPORT STATUS PANEL
	private JProgressBar importProgressBar;
	private JLabel importLabel;
	
	// MAIN IMPORT BUTTON
	private JButton resetButton;
	private JButton defaultButton;
	private JButton importButton;

	private JRadioButton generateRadio;
	private JRadioButton customRadio;

	private JCheckBox forceBox;
	private JTextField toleranceField;
	
	
	public GraphicalInterface()
	{
		super();
		frame = new JFrame(TITLE);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		
		
		
		
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				prefs.putInt(InterfaceConst.GuiPref.TAG_WIDTH, frame.getWidth());
				prefs.putInt(InterfaceConst.GuiPref.TAG_HEIGHT, frame.getHeight());
				prefs.putInt(InterfaceConst.GuiPref.TAG_X, frame.getX());
				prefs.putInt(InterfaceConst.GuiPref.TAG_Y, frame.getY());
			}
		});
		
		this.prefs = Preferences.userNodeForPackage(MainExecutable.class);
		
		frame.setMaximumSize(Toolkit.getDefaultToolkit().getScreenSize());
		
		JPanel mainPanel = new JPanel();
		JPanel filePanel = new JPanel();
		JPanel optionPanel = new JPanel();
		//advancedOptionPanel = new JPanel();
		JPanel buttonPanel = new JPanel();
		
		filePanel.setBorder(BorderFactory.createTitledBorder("File"));
		//optionPanel.setBorder(BorderFactory.createTitledBorder("Options"));
		
		
		
		advancedCheckBox = new JCheckBox("Advanced Options");
		advancedCheckBox.addActionListener(this);
		
		fileField = new JTextField();
		fileField.setEditable(false);
		
		toleranceField = new JTextField();
		toleranceField.setColumns(10);
		
		clearBox = new JCheckBox("Clear Database");
		forceBox = new JCheckBox("Force Import");
		browseButton = new JButton("Browse");
		browseButton.addActionListener(this);
		delimiterField = new JTextField();
		subdelimiterField = new JTextField();
		
		importButton = new JButton("Import");
		importButton.addActionListener(this);
		
		//
		//		FILE PANEL LAYOUT
		//
		
		GroupLayout filePanelLayout = new GroupLayout(filePanel);
		filePanelLayout.setHorizontalGroup(
				filePanelLayout.createSequentialGroup()
					.addComponent(fileField)
					.addComponent(browseButton)
		);
		filePanelLayout.setVerticalGroup(
				filePanelLayout.createParallelGroup()
					.addComponent(fileField, GroupLayout.Alignment.CENTER, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
					.addComponent(browseButton, GroupLayout.Alignment.CENTER)
		);
		filePanel.setLayout(filePanelLayout);
		
		//
		//		OPTIONS PANEL
		//
		
		
		
		serverIPField = new JTextField();
		serverPortField = new JTextField();

		usernameField = new JTextField();
		passwordField = new JPasswordField();
		
		serverTypeCombo = new JComboBox(SQLDatabase.SUPPORTED_DB_SYSTEMS);
		
		customStringField = new JTextField();
		customStringField.addFocusListener(this);
		databaseNameField = new JTextField();
		tableNameField = new JTextField();
		
		generateRadio = new JRadioButton("Generate Connection String");
		customRadio = new JRadioButton("Custom Connection String");
		
		generateRadio.addActionListener(this);
		customRadio.addActionListener(this);
		
		ButtonGroup group = new ButtonGroup();
	    group.add(generateRadio);
	    group.add(customRadio);
		
		//delimiterField.setColumns(10);
		//subdelimiterField.setColumns(10);
		
		JSeparator importSeparator = new JSeparator(SwingConstants.HORIZONTAL);
		JSeparator serverConnectionSeparator = new JSeparator(SwingConstants.HORIZONTAL);
		JSeparator databaseSeparator = new JSeparator(SwingConstants.HORIZONTAL);
		JSeparator serverAuthenticationSeparator = new JSeparator(SwingConstants.HORIZONTAL);
		
		JLabel importOptionsLabel = new OptionsLabel("Import Options");
	    JLabel serverConnectionOptionsLabel = new OptionsLabel("Server Connection Options");
		JLabel serverAuthenticationOptionsLabel = new OptionsLabel("Server Authentication Options");
		JLabel databaseOptionsLabel = new OptionsLabel("Database Options");
		
	    JLabel delimiterLabel = new JLabel("delimiter:");
		JLabel subdelimiterLabel = new JLabel("subdelimiter:");
		JLabel serverTypeLabel = new JLabel("Server Type:");
		JLabel serverIPLabel = new JLabel("Server IP:");
		JLabel serverPortLabel = new JLabel("Server Port:");
		JLabel usernameLabel = new JLabel("Username:");
		JLabel passwordLabel = new JLabel("Password:");
		JLabel databaseNameLabel = new JLabel("Database Name:");
		JLabel tableNameLabel = new JLabel("Table Name:");
		JLabel customStringLabel = new JLabel("Custom String:");
		JLabel toleranceLabel = new JLabel("Error Tolerance:");
		
		GroupLayout optionPanelLayout = new GroupLayout(optionPanel);
		
		optionPanelLayout.setHorizontalGroup(
			optionPanelLayout.createParallelGroup()
				//.addComponent(advancedCheckBox, GroupLayout.Alignment.TRAILING)
				.addGroup(
					optionPanelLayout.createSequentialGroup()
						.addGap(OPTIONSLABEL_GAP)
						.addComponent(importOptionsLabel)
						.addComponent(importSeparator)
						.addGap(OPTIONSLABEL_GAP)
				)
				.addGroup(
					optionPanelLayout.createSequentialGroup()
						.addGap(OPTIONSLABEL_GAP)
						.addComponent(serverConnectionOptionsLabel)
						.addComponent(serverConnectionSeparator)
						.addGap(OPTIONSLABEL_GAP)
				)
				.addGroup(
					optionPanelLayout.createSequentialGroup()
						.addGap(OPTIONSLABEL_GAP)
						.addComponent(serverAuthenticationOptionsLabel)
						.addComponent(serverAuthenticationSeparator)
						.addGap(OPTIONSLABEL_GAP)
				)
				.addGroup(
					optionPanelLayout.createSequentialGroup()
						.addGap(OPTIONSLABEL_GAP)
						.addComponent(databaseOptionsLabel)
						.addComponent(databaseSeparator)
						.addGap(OPTIONSLABEL_GAP)
				)
				.addGroup(
					optionPanelLayout.createSequentialGroup()
						.addGap(FIELDLABEL_GAP)
						.addGroup(
							optionPanelLayout.createParallelGroup()
								.addComponent(generateRadio)
								.addComponent(customRadio)
						)
				)
				.addGroup(
					optionPanelLayout.createSequentialGroup()
						.addGap(FIELDLABEL_GAP)
						.addGroup(
							// FIELD LABELS
							optionPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
								.addComponent(delimiterLabel)
								.addComponent(subdelimiterLabel)
								.addComponent(toleranceLabel)
								.addComponent(tableNameLabel)
								.addComponent(serverTypeLabel)
								.addComponent(usernameLabel)
								.addComponent(passwordLabel)
								.addGroup(
									optionPanelLayout.createSequentialGroup()
										.addGap(TABBELLABEL_GAP)
										.addGroup(
												optionPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
													.addComponent(serverIPLabel)
													.addComponent(serverPortLabel)
													.addComponent(databaseNameLabel)
													.addComponent(customStringLabel)
										)
								)
						)
						.addGroup(
							optionPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
								.addComponent(delimiterField)
								.addComponent(subdelimiterField)
								.addComponent(forceBox)
								.addComponent(toleranceField)
								.addComponent(clearBox)
								.addComponent(tableNameField)
								.addComponent(serverTypeCombo)
								.addComponent(serverIPField)
								.addComponent(serverPortField)
								.addComponent(databaseNameField)
								.addComponent(customStringField)
								.addComponent(usernameField)
								.addComponent(passwordField)
						)
						.addGap(OPTIONSLABEL_GAP)
				)
		);
		
		optionPanelLayout.setVerticalGroup(
			optionPanelLayout.createSequentialGroup()
				//.addComponent(advancedCheckBox)
				
				// IMPORT OPTIONS
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(importOptionsLabel)
						.addComponent(importSeparator, GroupLayout.Alignment.CENTER, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
				)
				.addGap(SMALL_GAP)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(delimiterLabel)
						.addComponent(delimiterField)
				)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(subdelimiterLabel)
						.addComponent(subdelimiterField)
				)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(forceBox)
				)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(toleranceLabel)
						.addComponent(toleranceField)
				)

				.addGap(INTEROPTIONS_GAP)
				// DATABASE OPTIONS
				
				.addGroup(
						optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
							.addComponent(databaseOptionsLabel)
							.addComponent(databaseSeparator, GroupLayout.Alignment.CENTER, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
				)
				.addGap(SMALL_GAP)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(clearBox)
				)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(tableNameLabel)
						.addComponent(tableNameField)
				)
				.addGap(INTEROPTIONS_GAP)
				// SERVER CONNECTION OPTIONS
				
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(serverConnectionOptionsLabel)
						.addComponent(serverConnectionSeparator, GroupLayout.Alignment.CENTER, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
				)
				.addGap(SMALL_GAP)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(serverTypeLabel)
						.addComponent(serverTypeCombo)
				)
				.addComponent(generateRadio)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(serverIPLabel)
						.addComponent(serverIPField)
				)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(serverPortLabel)
						.addComponent(serverPortField)
				)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(databaseNameLabel)
						.addComponent(databaseNameField)
				)
				.addComponent(customRadio)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(customStringLabel)
						.addComponent(customStringField)
				)
				.addGap(INTEROPTIONS_GAP)
				// SERVER AUTHENTICATION OPTIONS
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(serverAuthenticationOptionsLabel)
						.addComponent(serverAuthenticationSeparator, GroupLayout.Alignment.CENTER, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
				)
				.addGap(SMALL_GAP)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(usernameLabel)
						.addComponent(usernameField)
				)
				.addGroup(
					optionPanelLayout.createParallelGroup(GroupLayout.Alignment.CENTER, false)
						.addComponent(passwordLabel)
						.addComponent(passwordField)
				)
				
		);
		
		optionPanel.setLayout(optionPanelLayout);
		
		
		//
		//		BUTTON PANEL LAYOUT
		//
		
		JPanel emptyButtonPanel = new JPanel();
		
		resetButton = new JButton("Reset");
		defaultButton = new JButton("Save As Default");
		
		resetButton.addActionListener(this);
		defaultButton.addActionListener(this);
		
		GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
		buttonPanelLayout.setHorizontalGroup(
				buttonPanelLayout.createSequentialGroup()
					.addGap(20)
					.addComponent(defaultButton)
					.addComponent(resetButton)
					.addComponent(emptyButtonPanel)
					.addComponent(importButton)
					.addGap(20)
		);
		buttonPanelLayout.setVerticalGroup(
				buttonPanelLayout.createParallelGroup()
					.addGap(10)
					.addComponent(defaultButton)
					.addComponent(resetButton)
					.addComponent(emptyButtonPanel, 0, 0, 0)
					.addComponent(importButton)
					.addGap(10)
		);
		buttonPanel.setLayout(buttonPanelLayout);
		
		
		//
		//	IMPORT STATUS PANEL
		//
		
		importProgressBar = new JProgressBar();
		importLabel = new JLabel("Waiting for user input...");
		
		JPanel importPanel = new JPanel();
		importPanel.setBorder(BorderFactory.createTitledBorder("Import Status"));
		
		GroupLayout importLayout = new GroupLayout(importPanel);
		importLayout.setHorizontalGroup(
				importLayout.createParallelGroup()
					.addGroup(
							importLayout.createSequentialGroup()
								.addContainerGap()
								.addComponent(importLabel)
								.addContainerGap()
					)
					.addGroup(
							importLayout.createSequentialGroup()
								.addContainerGap()
								.addComponent(importProgressBar)
								.addContainerGap()
					)
		);
		importLayout.setVerticalGroup(
				importLayout.createSequentialGroup()
					//.addContainerGap()
					.addComponent(importLabel)
					//.addContainerGap()
					.addComponent(importProgressBar)
					.addContainerGap()
		);
		importPanel.setLayout(importLayout);
		
		JLabel infoLabel = new JLabel(	"Select a file and make sure all options are set correctly before importing...");
										//+ "You can use this interface to set the options for the command-line interface by clicking the 'Save As Default'-Button on the lower righthand side.");
		
		//infoLabel.setVisible(false);
		
		
		
		//infoLabelWrapper.setLayout(infoLabelLayout);
		
		optionPanelWrapper = new JPanel();
		optionPanelWrapper.setBorder(BorderFactory.createTitledBorder("Options"));
		
		JPanel emptyPanel = new JPanel();
		
		JScrollPane optionScrollPane = new JScrollPane(optionPanel);
		optionScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		optionScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		optionScrollPane.setBorder(BorderFactory.createEmptyBorder());
		
		GroupLayout optionsWrapperLayout = new GroupLayout(optionPanelWrapper);
		optionsWrapperLayout.setHorizontalGroup(
				optionsWrapperLayout.createParallelGroup()
					.addComponent(advancedCheckBox, GroupLayout.Alignment.TRAILING)
					.addComponent(optionScrollPane)
					.addComponent(emptyPanel)
		);
		optionsWrapperLayout.setVerticalGroup(
				optionsWrapperLayout.createSequentialGroup()
					.addComponent(advancedCheckBox)
					.addComponent(optionScrollPane)
					.addComponent(emptyPanel)
		);
		optionPanelWrapper.setLayout(optionsWrapperLayout);
		
		GroupLayout layout = new GroupLayout(mainPanel);
		
		
		layout.setHorizontalGroup(
				layout.createParallelGroup()
					.addGroup(
							layout.createSequentialGroup()
								.addGap(20)
								.addComponent(infoLabel)
								.addGap(20)
					)
					.addComponent(filePanel)
					.addComponent(optionPanelWrapper)
					//.addComponent(emptyPanel)
					.addComponent(importPanel)
					.addComponent(buttonPanel)
		);
		
		layout.setVerticalGroup(
				layout.createSequentialGroup()
					.addGroup(
							layout.createSequentialGroup()
								.addGap(20)
								.addComponent(infoLabel)
								.addGap(20)
					)
					.addComponent(filePanel)
					.addComponent(optionPanelWrapper)
					//.addComponent(emptyPanel)
					.addComponent(importPanel)
					.addComponent(buttonPanel)
		);
		
		mainPanel.setLayout(layout);
		
		frame.getContentPane().add(mainPanel);
		frame.pack();
		
		advancedOptions = new ComponentGroup(new Component[] {forceBox, 
				toleranceLabel, toleranceField,
				databaseOptionsLabel, databaseSeparator,
				clearBox,
				tableNameLabel, tableNameField,
				serverConnectionOptionsLabel, serverConnectionSeparator,
				serverTypeLabel, serverTypeCombo,
				generateRadio,
				serverIPLabel, serverIPField,
				serverPortLabel, serverPortField,
				databaseNameLabel, databaseNameField,
				customRadio,
				customStringLabel, customStringField,
				serverAuthenticationOptionsLabel, serverAuthenticationSeparator,
				usernameLabel, usernameField,
				passwordLabel, passwordField
		});
		advancedOptions.setVisible(false);
		
		frame.getContentPane().add(mainPanel);
		frame.pack();
		frame.setMinimumSize(frame.getSize());
		
		frame.setSize(prefs.getInt(InterfaceConst.GuiPref.TAG_WIDTH, frame.getWidth()), prefs.getInt(InterfaceConst.GuiPref.TAG_HEIGHT, frame.getHeight()));
		frame.setLocation(prefs.getInt(InterfaceConst.GuiPref.TAG_X, frame.getX()), prefs.getInt(InterfaceConst.GuiPref.TAG_Y, frame.getY()));
		
		
		ComponentGroup fieldsGroup = new ComponentGroup(
				new Component[] {serverIPField, serverPortField, usernameField, passwordField, databaseNameField, tableNameField, customStringField, toleranceField, delimiterField, subdelimiterField}
		);
		fieldsGroup.addFocusListener(this);
		
		loadGUIPreferences();
	}
	
	private void loadGUIPreferences() {
		clearBox.setSelected(super.clearDB);
		forceBox.setSelected(super.forceImport);
		
		usernameField.setText(super.username);
		passwordField.setText(super.password);
		fileField.setText(super.filepath);
		
		tableNameField.setText(super.tableName);
		delimiterField.setText(super.delimiter);
		subdelimiterField.setText(super.subdelimiter);
	
		//System.out.println(errorTolerance);
		toleranceField.setText(Integer.toString(super.errorTolerance));
		serverTypeCombo.setSelectedIndex(super.dbSystemIndex);
		
		serverPortField.setText(prefs.get(InterfaceConst.GuiPref.TAG_SERVERPORT, InterfaceConst.BasicPref.PREF_NOTFOUND));
		customStringField.setText(prefs.get(InterfaceConst.GuiPref.TAG_CONNECTIONSTRING, InterfaceConst.BasicPref.PREF_NOTFOUND));
		serverIPField.setText(prefs.get(InterfaceConst.GuiPref.TAG_SERVERIP, InterfaceConst.BasicPref.PREF_NOTFOUND));
		databaseNameField.setText(prefs.get(InterfaceConst.GuiPref.TAG_DBNAME, InterfaceConst.BasicPref.PREF_NOTFOUND));
		customRadio.setSelected(prefs.get(InterfaceConst.GuiPref.TAG_CUSTOMSTRING, InterfaceConst.BasicPref.PREF_NOTFOUND).equals("true"));
		generateRadio.setSelected(prefs.get(InterfaceConst.GuiPref.TAG_GENERATESTRING, InterfaceConst.BasicPref.PREF_NOTFOUND).equals("true"));
		advancedCheckBox.setSelected(prefs.get(InterfaceConst.GuiPref.TAG_ADVANCEDOPTIONS, InterfaceConst.BasicPref.PREF_NOTFOUND).equals("true"));
		
		enableFields();
		enableAdvancedOptions();
	}
	
	private void saveGUIPreferences()
	{
		try {
			bindOptions();
		} catch (Exception e) {
		}
		super.errorTolerance = Integer.parseInt(toleranceField.getText().trim());
		super.savePreferences();
		prefs.put(InterfaceConst.GuiPref.TAG_SERVERPORT, serverPortField.getText().trim());
		prefs.put(InterfaceConst.GuiPref.TAG_SERVERIP, serverIPField.getText().trim());
		prefs.put(InterfaceConst.GuiPref.TAG_CONNECTIONSTRING, customStringField.getText().trim());
		prefs.put(InterfaceConst.GuiPref.TAG_DBNAME, databaseNameField.getText().trim());
		
		if (generateRadio.isSelected()) prefs.put(InterfaceConst.GuiPref.TAG_GENERATESTRING, "true");
		else prefs.put(InterfaceConst.GuiPref.TAG_GENERATESTRING, "false");
		
		if (customRadio.isSelected()) prefs.put(InterfaceConst.GuiPref.TAG_CUSTOMSTRING, "true");
		else prefs.put(InterfaceConst.GuiPref.TAG_CUSTOMSTRING, "false");
		
		if (advancedCheckBox.isSelected()) prefs.put(InterfaceConst.GuiPref.TAG_ADVANCEDOPTIONS, "true");
		else prefs.put(InterfaceConst.GuiPref.TAG_ADVANCEDOPTIONS, "false");
	}

	public void enableFields()
	{
		serverIPField.setEnabled(generateRadio.isSelected());
		serverPortField.setEnabled(generateRadio.isSelected());
		//userNameField.setEnabled(generateRadio.isSelected());
		//userPasswordField.setEnabled(generateRadio.isSelected());
		databaseNameField.setEnabled(generateRadio.isSelected());
		//dbTableField.setEnabled(generateRadio.isSelected());
		//dbSystemCombo.setEnabled(generateRadio.isSelected());
		
		customStringField.setEnabled(customRadio.isSelected());
		
	}
	
	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource().equals(resetButton))
		{
			loadGUIPreferences();
			importProgressBar.setValue(0);
			importLabel.setText("Waiting for user input...");
		}
		else if (arg0.getSource().equals(defaultButton))
			saveGUIPreferences();
		else if (arg0.getSource().equals(advancedCheckBox))
		{
			enableAdvancedOptions();
		}
		else if (arg0.getSource().equals(browseButton))
		{
			JFileChooser d = new JFileChooser();
			d.setFileSelectionMode(JFileChooser.FILES_ONLY);
			d.setAcceptAllFileFilterUsed(false);
			SupportedFileFilter filter = new SupportedFileFilter();
			d.addChoosableFileFilter(filter);
			d.addChoosableFileFilter(new TTDFFileFilter());
			d.addChoosableFileFilter(new TXTFileFilter());
			
			d.setFileFilter(filter);
			
			File f = new File(fileField.getText());
			if (f.exists()) d.setSelectedFile(f);
			
			int returnVal = d.showOpenDialog(frame);
			if (returnVal == JFileChooser.APPROVE_OPTION) 
			{
				fileField.setText(d.getSelectedFile().getPath());
			}
		}
		else if (arg0.getSource().equals(importButton))
		{
			try {
				bindOptions();
				super.run();
			} catch (BindingException e) {
				JOptionPane.showMessageDialog(frame, e.getMessage(), "No Connection String Selected", JOptionPane.ERROR_MESSAGE);
				importLabel.setText("Some errors occurred during installation");
			}
		}
		else if (arg0.getSource().equals(customRadio) || arg0.getSource().equals(generateRadio))
		{
			enableFields();
		}
	}
	
	private void enableAdvancedOptions()
	{
		advancedOptions.setVisible(advancedCheckBox.isSelected());
		frame.validate();
	}
	
	@Override 
	public void run()
	{
		frame.setVisible(true);
	}

	@Override
	protected void handleDriverNotFoundException(DriverNotFoundException e) {
		JOptionPane.showMessageDialog(frame, e.getMessage(), "Driver Error", JOptionPane.ERROR_MESSAGE);
		//importLabel.setText("Some errors occurred during installation");
		//e.printStackTrace();
	}

	@Override
	protected void handleIOException(IOException e) {
		JOptionPane.showMessageDialog(frame, e.getMessage(), "I/O Error", JOptionPane.ERROR_MESSAGE);
		importLabel.setText("Some errors occurred during installation");
		//e.printStackTrace();
	}

	@Override
	protected void handleSQLException(SQLException e) {
		JOptionPane.showMessageDialog(frame, e.getMessage(), "SQL Error", JOptionPane.ERROR_MESSAGE);
		importLabel.setText("Some errors occurred during installation");
		//e.printStackTrace();
	}

	@Override
	protected void handleTableParserErrors(TimeTableParserErrors e) {
		if (!super.forceImport)
		{
			ParserErrorDialog d = new ParserErrorDialog(frame, e);
			d.setVisible(true);
		}
		importLabel.setText("Some errors occurred during installation");
	}

	@Override
	protected void handleToleranceReachedException(ToleranceReachedException e) {
		JOptionPane.showMessageDialog(frame, "The number of errors has reached the tolerance. Please make\n" +
				"sure you've selected the correct file. This might indicate\n" +
				"a wrong fileformat.", "ToleranceReachedException", JOptionPane.ERROR_MESSAGE);
		importLabel.setText("Some errors occurred during installation");
		//e.printStackTrace();
	}
	
	@Override
	protected void handleInterfaceNotFoundException(InterfaceNotFoundException e) {
		JOptionPane.showMessageDialog(frame, e.getMessage(), "SQLInterface not found", JOptionPane.ERROR_MESSAGE);
		importLabel.setText("Some errors occurred during installation");
	}

	@Override
	protected void postRun() {
		
	}

	@Override
	protected boolean preRun() {
		
		return true;
	}

	@Override
	protected void printProgressInfo(String message) {
		importLabel.setText(message);
	}

	@Override
	protected void progressUpdate(int percent) {
		importProgressBar.setValue(percent);
	}
	
	private void bindOptions() throws BindingException
	{
		super.clearDB = clearBox.isSelected();
		super.forceImport = forceBox.isSelected();
		
		super.username = usernameField.getText();
		super.password = StringTools.charArrayToString(passwordField.getPassword());
		super.filepath = fileField.getText();
		
		super.tableName = tableNameField.getText();
		super.delimiter = delimiterField.getText();
		super.subdelimiter = subdelimiterField.getText();
		
		try { super.errorTolerance = Integer.parseInt(toleranceField.getText().trim()); }
		catch (NumberFormatException e) {}
		
		super.dbSystemIndex = serverTypeCombo.getSelectedIndex();
		
		String connectionString = "";
		if (generateRadio.isSelected())
		{
			connectionString = "jdbc:" + SQLDatabase.SUPPORTED_DB_SYSTEMS[serverTypeCombo.getSelectedIndex()].toLowerCase() + "://" + serverIPField.getText().trim() + ":" + serverPortField.getText().trim() + "/" + databaseNameField.getText().trim();
		}
		else if (customRadio.isSelected())
		{
			connectionString = customStringField.getText().trim();
		}
		else 
		{
			throw new BindingException("No Connection String method selected.\n" +
								"Please select either 'Generate Connection String'\n" +
								"or 'Custom Connection String'");
		}
		
		super.connectionString = connectionString;
	}

	public void focusGained(FocusEvent e) {
		if (e.getSource().getClass().toString().equals("class javax.swing.JTextField"))
		{
			if (((JTextField) e.getSource()).getText().equals(InterfaceConst.BasicPref.PREF_NOTFOUND))
			{
				((JTextField) e.getSource()).setText("");
			}
		}
		else if (e.getSource().getClass().toString().equals("class javax.swing.JPasswordField"))
		{
			if (((JTextField) e.getSource()).getText().equals(InterfaceConst.BasicPref.PREF_NOTFOUND))
			{
				((JTextField) e.getSource()).setText("");
			}
		}
	}

	public void focusLost(FocusEvent e) {
		
		if (e.getSource().getClass().toString().equals("class javax.swing.JTextField"))
		{
			if (((JTextField) e.getSource()).getText().equals(""))
			{
				((JTextField) e.getSource()).setText(InterfaceConst.BasicPref.PREF_NOTFOUND);
			}
		}
	}

	
}
